package org.beian.fmmall.service.Impl;

import org.beian.fmmall.VO.ResStatus;
import org.beian.fmmall.VO.ResultVO;
import org.beian.fmmall.beans.*;
import org.beian.fmmall.dao.OrderItemMapper;
import org.beian.fmmall.dao.OrdersMapper;
import org.beian.fmmall.dao.ProductSkuMapper;
import org.beian.fmmall.dao.ShoppingCartMapper;
import org.beian.fmmall.service.OrderService;
import org.beian.fmmall.utils.PageHelper;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Transactional
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private OrdersMapper ordersMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private ProductSkuMapper productSkuMapper;
    @Autowired
    private RedissonClient redissonClient;

    private Logger logger=LoggerFactory.getLogger(OrderServiceImpl.class);
    public ResultVO addOrder(String cids, Orders order) {
        //1、根据cids查询商品信息(订单名称，检查库存是否足够)
        String[] arr=cids.split(",");
        List<Integer> cartIds=new ArrayList<>();
        for(int i=0;i<arr.length;i++){
            cartIds.add(Integer.parseInt(arr[i]));
        }
        List<ShoppingCartVO> shoppingCartVOS = shoppingCartMapper.selectShopCartByCids(cartIds);
        //看门狗机制
        boolean isLock=true;
        String[] skuIds=new String[shoppingCartVOS.size()];
        Map<String, RLock> locks=new HashMap<>();
        for(int i=0;i<shoppingCartVOS.size();i++){
            String skuId=shoppingCartVOS.get(i).getSkuId();
            RLock lock = redissonClient.getLock(skuId);
            boolean b = false;
            try {
                b = lock.tryLock(10, 3, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if(b){
                skuIds[i]=skuId;
                locks.put(skuId,lock);
            }else{
                break;
            }
            isLock=isLock&b;
        }
        try {
            if(isLock){//所有商品都加锁成功

                //再查询一遍库存，防止在上一次查询与加锁之间，有线程修改了数据
                shoppingCartVOS = shoppingCartMapper.selectShopCartByCids(cartIds);
                //2、检查库存是否充足
                boolean f=true;
                String untitled="";
                //生成订单编号
                String orderId= UUID.randomUUID().toString().replace("-","");
                for (ShoppingCartVO shoppingCartVO : shoppingCartVOS) {
                    if(Integer.parseInt(shoppingCartVO.getCartNum())>shoppingCartVO.getStock()){
                        f=false;
                    }
                    //获取商品名称，用，拼接
                    untitled=untitled+shoppingCartVO.getProductName()+",";

                }
                if(f){
                    //商品充足
                    order.setUntitled(untitled);
                    order.setCreateTime(new Date());
                    order.setOrderId(orderId);
                    order.setStatus("1");
                    //保存订单
                    int i = ordersMapper.insert(order);
                    if(i>0){
                        //保存商品快照
                        for (ShoppingCartVO shoppingCartVO : shoppingCartVOS) {
                            //生成商品快照，供后面使用
                            String itemId=System.currentTimeMillis()+""+new Random().nextInt(89999)+10000;
                            OrderItem orderItem = new OrderItem(itemId,orderId,shoppingCartVO.getProductId(),shoppingCartVO.getProductName(),shoppingCartVO.getProductImg(),shoppingCartVO.getSkuId(),shoppingCartVO.getSkuName(),new BigDecimal(shoppingCartVO.getSellPrice()),Integer.parseInt(shoppingCartVO.getCartNum()),new BigDecimal(Integer.parseInt(shoppingCartVO.getCartNum())*shoppingCartVO.getSellPrice()),new Date(),new Date(),0);
                            int m = orderItemMapper.insert(orderItem);
                        }
                        //扣减库存
                        for (ShoppingCartVO cartVO : shoppingCartVOS) {
                            String skuId = cartVO.getSkuId();
                            int newStock=cartVO.getStock()-Integer.parseInt(cartVO.getCartNum());
                            ProductSku productSku = new ProductSku();
                            productSku.setSkuId(skuId);
                            productSku.setStock(newStock);
                            int k = productSkuMapper.updateByPrimaryKeySelective(productSku);
                        }
                    }
                    //删除购物车记录
                    for (Integer cartId : cartIds) {
                        int i1 = shoppingCartMapper.deleteByPrimaryKey(cartId);
                    }
                    HashMap<String,String> map=new HashMap<>();
                    map.put("orderId",orderId);
                    map.put("untitled",untitled);

                    return new ResultVO(ResStatus.OK,"下单成功",map);
                }else{
                    //库存不足
                    return new ResultVO(ResStatus.NO,"库存不足，下单失败！",null);
                }

            }
        } catch (NumberFormatException e) {
            throw new RuntimeException(e);
        } finally {
            for(int i=0;i< locks.size();i++){
                String s=skuIds[i];
                locks.get(s).unlock();
            }
        }
        return null;

    }

    @Override
    public int updateOrderStatus(String orderId, String status) {
        Orders order = new Orders();
        order.setOrderId(orderId);
        order.setStatus(status);
        int i = ordersMapper.updateByPrimaryKeySelective(order);
        return i;
    }

    @Override
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public void closeOrder(String orderId) {
        Orders orders1 = new Orders();
        orders1.setOrderId(orderId);
        orders1.setStatus("6");
        orders1.setCloseType(1);
        ordersMapper.updateByPrimaryKeySelective(orders1);
        //c.还原库存
        Example example1 = new Example(OrderItem.class);
        Example.Criteria criteria1 = example1.createCriteria();
        criteria1.andEqualTo("orderId",orderId);
        List<OrderItem> orderItemList = orderItemMapper.selectByExample(example1);
        for (int j = 0; j < orderItemList.size(); j++) {
            OrderItem orderItem = orderItemList.get(j);
            ProductSku productSku = productSkuMapper.selectByPrimaryKey(orderItem.getSkuId());
            productSku.setStock(productSku.getStock()+orderItem.getBuyCounts());
            productSkuMapper.updateByPrimaryKey(productSku);
        }
    }

    @Override
    public ResultVO listOrders(String userId, String status, int pageNum, int limit) {
        int start=(pageNum-1)*limit;
        List<OrdersVO> ordersVOList = ordersMapper.getOrdersBystatus(userId, status, start, limit);
        Example example = new Example(Orders.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId",userId);
        if(status!=null && !status.equals("")){
            criteria.andEqualTo("status",status);
        }
        int count = ordersMapper.selectCountByExample(example);
        int pageCount=count%limit==0?count/limit:count/limit+1;
        PageHelper<OrdersVO> pageHelper = new PageHelper<>(count, pageCount, ordersVOList);
        ResultVO resultVO = new ResultVO(ResStatus.OK, "success", pageHelper);
        return resultVO;
    }
}
